package com.wits.qso.web.controller;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springside.modules.web.Servlets;

import com.wits.platform.common.constants.ViewType;
import com.wits.platform.common.constants.WebConstants;
import com.wits.platform.common.utils.FileUtil;
import com.wits.platform.common.utils.PageUtil;
import com.wits.platform.common.utils.StringUtil;
import com.wits.platform.web.controller.BaseController;
import com.wits.platform.web.mvc.PageParam;
import com.wits.qso.dao.impl.MaterialHDaoImpl.Material;
import com.wits.qso.entity.Attachment;
import com.wits.qso.entity.Course;
import com.wits.qso.entity.MaterialD;
import com.wits.qso.entity.MaterialH;
import com.wits.qso.service.CourseService;
import com.wits.qso.service.MaterialHService;
import com.wits.qso.service.MaterialdService;


@Controller
@RequestMapping(value = "qso/material")
public class MaterialController extends BaseController
{
	protected static final String ATTR_COURSE_TITLE = "courses";
	protected static final String ATTR_MARTERIALD = "materialD";
	// protected static final String ATTR_MARTERIAL_INTRO = "materialIntro";
	// protected static final String ATTR_MARTERIAL_TITLE = "materialTitle";
	// protected static final String ATTR_PARENT = "parent";
	private static String ATTR_ATTACHMENT_NAME = "attachmentName";
	private static String ATTR_ATTACHMENT_SIZE = "attachmentSize";

	@Autowired
	private CourseService courseService = null;
	@Autowired
	private MaterialdService materialdService = null;
	@Autowired
	private MaterialHService materialHService = null;

	@RequestMapping(value = "/toList")
	public String toList() {
		return "qso/material/list";
	}

	@RequestMapping(value = "/list")
	@ResponseBody
	public String list(Model model, @ModelAttribute("page")
	PageParam page, HttpServletRequest request) {
		Map<String, Object> searchParams = Servlets.getParametersStartingWith( request, "search_" );

		Page<Material> listPage = materialHService.findMaterials( searchParams );

		model.addAttribute( "searchParams", Servlets.encodeParameterStringWithPrefix( searchParams, "search_" ) );

		return PageUtil.toAjaxPageResult( listPage.getTotalElements(), listPage.getContent() );
	}

	@RequestMapping(value = "/view/{viewType}")
	public String toView(Model model, @PathVariable
	String viewType, @RequestParam(value = "id")
	String id) {
		if (ViewType.Add.getView().equals( viewType )) {
			model.addAttribute( WebConstants.COMMAND, new MaterialH() );
		} else {
			model.addAttribute( WebConstants.COMMAND, materialHService.getOne( id ) );
			// MaterialD materialD = ;

			model.addAttribute( ATTR_MARTERIALD, materialdService.findDetail( id ) );
			// model.addAttribute( ATTR_MARTERIAL_INTRO, materialD.getIntro() );
			// model.addAttribute( ATTR_MARTERIAL_TITLE, materialD.getTitle() );
			// model.addAttribute( ATTR_PARENT, courseService.getOne( materialD.getUpId() ) );
		}

		model.addAttribute( ATTR_COURSE_TITLE, courseService.findAll() );
		model.addAttribute( "viewType", viewType );

		return "qso/material/form";
	}

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/save", method = RequestMethod.POST)
	@ResponseBody
	public Object save(Model model, @ModelAttribute("command")
	@Valid
	MaterialH command, BindingResult result, @RequestParam(value = "viewType")
	String viewType, @RequestParam String couid,@RequestParam(value = "materialIntro")
	String materialIntro,
	// @RequestParam(value = "parentId") String parentId
			HttpSession session) {
		MaterialD materialD = null;

		List<MaterialH> materialHList=new ArrayList<MaterialH>();
		List<MaterialD> materialDList=new ArrayList<MaterialD>();
		
		List<String> fileNameList=(List<String>) session.getAttribute(ATTR_ATTACHMENT_NAME);
		List<Long> fileSizeList=(List<Long>) session.getAttribute(ATTR_ATTACHMENT_SIZE);
		
		if(fileNameList==null){
			session.removeAttribute( ATTR_ATTACHMENT_NAME );
			session.removeAttribute( ATTR_ATTACHMENT_SIZE );
			return ajaxDoneError( "请先上传附件" );
		}
		
		command.setCouid(courseService.getOne(couid));

		if (ViewType.Add.getView().equals( viewType )) {
			for (int i = 0; i < fileNameList.size(); i++) {
				materialD = new MaterialD();
				materialD.setDateCre( new Date() );
				materialD.setUserCre( getCurrentUserId() );

				command.setDateCre( new Date() );
				command.setUserCre( getCurrentUserId() );
				
				materialHList.add(command);
				materialDList.add(materialD);
			}
			
		} else {
			if (materialdService.isExisted( command.getId() )) {
				materialD = materialdService.findDetail( command.getId() );
				materialD.setDateUpd( new Date() );
				materialD.setUserUpd( getCurrentUserId() );
			} else {
				materialD = new MaterialD();
				materialD.setDateCre( new Date() );
				materialD.setUserCre( getCurrentUserId() );
			}

			command.setDateUpd( new Date() );
			command.setUserUpd( getCurrentUserId() );
			
			materialHList.add(command);
			materialDList.add(materialD);
		}

		try {
			command.setUserId( getCurrentUserId() );
			
			if(fileNameList!=null && fileNameList.size()>0 
					&&fileSizeList!=null && fileSizeList.size()>0){

				for (int i = 0; i < materialHList.size(); i++) {
					
					command = materialHService.save( materialHList.get(i) );

					logger.info( " save materialD {}", command );

					materialDList.get(i).setTitle(fileNameList.get(i).substring(0,fileNameList.get(i).lastIndexOf(".")));
					materialDList.get(i).setPath(fileNameList.get(i) );
					materialDList.get(i).setSizs( fileSizeList.get(i).floatValue() / 1024 / 1024 );
					materialDList.get(i).setMtrhId( command.getId() );
					materialDList.get(i).setUpId( "" );
					// materialD.setUpId( (courseService.findByTitle( command.getCouName() )).getId() );
					materialDList.get(i).setUri( "download/material/" + fileNameList.get(i));
					materialDList.get(i).setIntro( materialIntro );
					materialdService.save( materialDList.get(i) );
				}
				session.removeAttribute( ATTR_ATTACHMENT_NAME );
				session.removeAttribute( ATTR_ATTACHMENT_SIZE );

				return ajaxDoneSuccess( this.getText( "save.success" ) );
			}else{
				session.removeAttribute( ATTR_ATTACHMENT_NAME );
				session.removeAttribute( ATTR_ATTACHMENT_SIZE );
				return ajaxDoneError( "请先上传附件" );
			}

		} catch (Exception e) {
			return ajaxDoneError( this.getText( "save.failed" ), e );
		}
	}

	@RequestMapping(value = "/delete")
	@ResponseBody
	public Object delete(String ids) {
		try {
			materialHService.deleteInBatch( Arrays.asList( StringUtil.split( ids, "," ) ) );

			return ajaxDoneSuccess( this.getText( "delete.success" ) );
		} catch (Exception e) {
			return ajaxDoneError( this.getText( "delete.failed" ), e );
		}
	}

	@RequestMapping(value = "/deleteMaterialD")
	@ResponseBody
	public Object deleteMaterialD(HttpServletRequest request, @RequestParam(value = "id")
	String id) {
		MaterialD materialD = materialdService.getOne( id );

		if (0 < materialdService.deleteById( id )) {
			File f = new File( request.getSession().getServletContext().getRealPath( "/" ) + "upload/material/" + materialD.getPath() );
			f.delete();
		}

		return "true";
	}

	@RequestMapping(value = "/courseJson")
	@ResponseBody
	public String getCourseJson() {
		Iterator<Course> courses = courseService.findAll().iterator();
		StringBuilder builder = new StringBuilder( "[" );

		builder.append( "{\"id\":\"root" ).append( "\",\"name\":\"启秀" ).append( "\",\"pId\":\"null" ).append( "\",\"type\":\"menu" )
				.append( "\",\"isParent\":true" ).append( "}," );

		while (courses.hasNext()) {
			Course course = courses.next();

			builder.append( "{\"id\":\"" ).append( course.getId() ).append( "\",\"name\":\"" ).append( course.getTitle() ).append( "\",\"pId\":\"root" )
					.append( "\",\"type\":\"menu" ).append( "\",\"isParent\":false" ).append( "}" );

			if (courses.hasNext()) {
				builder.append( "," );
			}
		}

		builder.append( "]" );

		return builder.toString();
	}

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/upload")
	public void upload(HttpServletRequest request, @RequestParam(value = "attachment")
	MultipartFile attachment, HttpSession session) {
		if (null != attachment) {
			logger.info( "{}, {}", attachment.getSize(), attachment.getOriginalFilename() );

			List<String> fileNameList=(List<String>) session.getAttribute(ATTR_ATTACHMENT_NAME);
			List<Long> fileSizeList=(List<Long>) session.getAttribute(ATTR_ATTACHMENT_SIZE);
			if(fileNameList==null || fileSizeList==null
					||fileNameList.size()==0
					||fileSizeList.size()==0){
				fileNameList=new ArrayList<String>();
				fileSizeList=new ArrayList<Long>();
			}
			fileNameList.add(attachment.getOriginalFilename());
			fileSizeList.add(attachment.getSize());
			session.setAttribute( ATTR_ATTACHMENT_NAME, fileNameList );
			session.setAttribute( ATTR_ATTACHMENT_SIZE, fileSizeList );
			try {
				FileUtil.upload( attachment, request.getSession().getServletContext().getRealPath( "/" ) + "download/material/",
						attachment.getOriginalFilename() );
			} catch (Throwable cause) {
				logger.error( cause.getMessage(), cause );
				session.removeAttribute( ATTR_ATTACHMENT_NAME );
				session.removeAttribute( ATTR_ATTACHMENT_SIZE );
			}
		}
	}

	@RequestMapping(value = "/download")
	public void download(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "materialId")
	String materialId) {
		String basePath = request.getSession().getServletContext().getRealPath( "/" );
		MaterialD materialD = materialdService.getOne( materialId );
		Attachment attachment = new Attachment();
		attachment.setOriginalName( materialD.getPath() );
		attachment.setFilePath( materialD.getUri() );
		String contentType = "application/octet-stream";
		FileUtil.download( response, basePath, contentType, attachment );
	}
}
